     //
//  NetworkManager.m
//  LBBase
//
//  Created by Gary on 15/7/1.
//  Copyright (c) 2015年 Lebo. All rights reserved.
//

#import "NetworkManager.h"
#import "CommonDefine.h"
#import "ConfigDefine.h"
#import "LBNetworkManager.h"
#import "LBRequestParameter.h"
#import "Common.h"

static const NSInteger kNMArrayCount = 3;//可同时发送网络请求的数目

@interface NetworkManager () <LBNetworkResponseDelegate> {
    NSArray<LBNetworkManager *> *_nmArr;
    NSMutableDictionary *_reqDic;
    NSMutableDictionary *_rspDic;
}

@end

@implementation NetworkManager

/**
 * @brief
 *
 * Detailed comments of this function
 * @param[in]
 * @param[out]
 * @return
 * @note
 */
- (id)init {
    self = [super init];
    
    if (self) {
        self.moduleID = ENetworkManager;
        
        NSMutableArray *arr = [NSMutableArray arrayWithCapacity:kNMArrayCount];
        for (int i = 0; i < kNMArrayCount; i++) {
            LBNetworkManager *nm = [[LBNetworkManager alloc] init];
            nm.delegate = self;
            nm.tag = i;
            [arr addObject:nm];
        }
        _nmArr = [NSArray arrayWithArray:arr];
        
        _reqDic = [[NSMutableDictionary alloc] init];
        _rspDic = [[NSMutableDictionary alloc] init];
        
        //将请求的网络地址和请求方法ID绑定
        [self registerNetReq:kNetReqNameGet funID:ENetGetReq];
        [self registerNetReq:kNetReqNamePost funID:ENetPostReq];
        
        /**
         *  LoginManager
         */
        [self registerNetReq:kNetReqPostLogin funID:ENetReqPostLogin];
        
        /**
         *  ProfileManager
         */
        [self registerNetReq:kNetReqPostGetProfile funID:ENetReqPostGetProfile];
        
        /**
         *  CarManager
         */
        [self registerNetReq:kNetReqPostGetBrandList funID:ENetReqPostGetBrandList];
    }
    
    return self;
}

- (void)registerNetReq:(const NSString*)requestStr funID:(NSInteger)funID {
    [_reqDic setObject:requestStr forKey:[NSNumber numberWithInteger:funID] ];
    [_rspDic setObject:[NSNumber numberWithInteger:funID] forKey:requestStr];
}

/**
 * @brief
 *
 * Detailed comments of this function
 * @param[in]
 * @param[out]
 * @return
 * @note
 */
- (void)dealloc {
    [_reqDic removeAllObjects];
    [_rspDic removeAllObjects];
    
#ifndef COMPILE_ARC_MODE
    [_nmArr removeAllObjects];
    [_nmArr release];
    [_reqDic release];
    [_rspDic release];
    
    [super dealloc];
#endif
}

#pragma mark - 自动登录后重新发送网络请求

- (void)retryRequestTasks {
    //LogFunc;
    for (LBNetworkManager *nm in _nmArr) {
        @synchronized(nm.retryRequestTasks) {
            NSMutableArray *arr = [NSMutableArray array];
            for (NSInteger i = 0; i < nm.retryRequestTasks.count; i++) {
                LBRequestParameter *param = [nm.retryRequestTasks objectAtIndex:i];
                BOOL exist = NO;
                for (LBRequestParameter *paramInArr in arr) {
                    NSString *url = [param.operation.userInfo objectForKey:kNetworkRequestName];
                    NSString *urlInArr = [paramInArr.operation.userInfo objectForKey:kNetworkRequestName];
                    if (url == urlInArr && [param.body isEqualToDictionary:paramInArr.body]) {
                        exist = YES;
                        break;
                    }
                }
                if (!exist) {
                    [arr addObject:param];
                }
            }
            [nm.retryRequestTasks removeAllObjects];
            //LogDebug(@"%lu tasks need to be retry", arr.count - 1);
            //重新发送retryRequestTasks保存的请求
            for (LBRequestParameter *param in arr) {
                NSNumber *req = [_rspDic objectForKey:[param.operation.userInfo objectForKey:kNetworkRequestName]];
                //登录请求一定不能再次发送，不然会形成递归调用，陷入死循环
                if (req.integerValue != ENetReqPostLogin) {
                    NSDictionary *dic = param.body;
                    [BF callBusinessFunc:BusinesID(ENetworkManager, req.intValue) inParam:dic];
                }
            }
        }
    }
}

- (void)clearRetryRequestTasks {
    LogFunc;
    for (LBNetworkManager *nm in _nmArr) {
        [nm.retryRequestTasks removeAllObjects];
    }
}

#pragma mark - 框架函数

//调用业务模块功能处理
/**
 * @brief
 *
 * Detailed comments of this function
 * @param[in]
 * @param[out]
 * @return
 * @note
 */
- (int)callBusinessFunc:(NSUInteger)funcID inParam:(id)inParam outParam:(id *)outParam {
    id nmIndex = [(NSDictionary*)inParam objectForKey:kNetworkRequestNMIndex];
    LBNetworkManager *nm = _nmArr[[nmIndex integerValue]];
    switch (funcID) {
        case ENetGetReq: {
            if (inParam) {
                NSString *requestStr = [_reqDic objectForKey:[NSNumber numberWithInteger:funcID]];
                NSString *requestUrl = [(NSDictionary*)inParam objectForKey:kNetworkRequestUrl];
                if (requestUrl) {
                    [nm getDataWithUrl:requestUrl params:inParam withCookie:NO];
                } else {
                    NSMutableDictionary *dic = [(NSDictionary*)inParam objectForKey:kNetworkRequestData];
                    SetService(dic, requestStr);    //车之宝特殊的请求方式
                    [nm getDataWithUrl:[Common baseServerURL] params:inParam withCookie:NO];
                }
            }
            break;
        }
            
            /**
             *  LoginManager
             */
        case ENetPostReq:
        case ENetReqPostLogin:
            
            /**
             *  ProfileManager
             */
        case ENetReqPostGetProfile:
            
            /**
             *  CarManager
             */
        case ENetReqPostGetBrandList: {
            if (inParam) {
                NSString *requestStr = [_reqDic objectForKey:[NSNumber numberWithInteger:funcID]];
                NSString *requestUrl = [(NSDictionary*)inParam objectForKey:kNetworkRequestUrl];
                if (requestUrl) {
                    [nm postJsonDataWithUrl:requestUrl params:inParam withCookie:NO];
                } else {
                    NSMutableDictionary *dic = [(NSDictionary*)inParam objectForKey:kNetworkRequestData];
                    SetService(dic, requestStr);    //车之宝特殊的请求方式
                    [nm postJsonDataWithUrl:[Common baseServerURL] params:inParam withCookie:NO];
                }
            }
            break;
        }
            
            //case ENetReqPostRegister: {
            //    if (inParam) {
            //        NSString *requestStr = [_reqDic objectForKey:[NSNumber numberWithInteger:funcID]];
            //        NSString *requestUrl = [(NSDictionary*)inParam objectForKey:kNetworkRequestUrl];
            //        if (requestUrl) {
            //            [nm postJsonDataWithUrl:requestUrl params:inParam withCookie:NO];
            //        } else {
            //            NSMutableDictionary *dic = [(NSDictionary*)inParam objectForKey:kNetworkRequestData];
            //            SetService(dic, requestStr);    //车之宝特殊的请求方式
            //            [nm postUploadWithUrl:[Common baseServerURL] params:inParam withCookie:NO];
            //        }
            //    }
            //    break;
            //}
            
        case ENetRetryAllRequestTasks: {
            [self retryRequestTasks];
            break;
        }
            
        case ENetClearRetryAllRequestTasks: {
            [self clearRetryRequestTasks];
            break;
        }
            
        default:
            break;
    }
    return 0;
}


/**
 * @brief 通知回调
 *
 * processBusinessNotify
 * @param[in] chatMember
 * @return N/A
 * @note
 */
- (void)onBusinessNotify:(NSUInteger)notifyID inParam:(id)inParam {
    switch (notifyID) {
        default:
            break;
    }
}

#pragma mark - delegate

- (void)didReceiveNetData:(NSData *)data requestName:(NSString *)request {
    //LogFunc;
    NSNumber *req = [_rspDic objectForKey:request];
    if (req) {
        [BF broadcastBusinessNotification:BusinesID(ENetworkManager, req.intValue) inParam:data];
    }
}

- (void)didFailWithNetRequest:(id)data requestName:(NSString*)request {
    LogFunc;
    NSNumber *req = [_rspDic objectForKey:request];
    if (req) {
        [BF broadcastBusinessNotification:BusinesID(ENetworkManager, req.intValue) inParam:data];
    }
}

@end